#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# TÜBİTAK/UEAKE
# Gökmen GÖKSEL (2008) <gokmen@pardus.org.tr>

import ConfigParser
import Exceptions
import Preconditions

DEVELOPER = "developer"

class Package:
    """ Provides package information """
    def __init__(self, packagename):
        self.packagename  = packagename
        self.homepage     = ''
        self.checkchanges = ''
        self.dependencies = ''

class Repo:
    """ Provides Repo information and packages """
    def __init__(self, reponame=''):
        self.reponame = reponame
        self.repoaddr = ''
        self.packages = []

    def addPackage(self, package, force=False):
        for node in self.packages:
            if package.packagename == node.packagename:
                if force:
                    self.packages.remove(package)
                else:
                    raise Exceptions.AlreadyExists, "Package %s is already in list, skipped." % package.packagename
        self.packages.append(package)

class Developer:
    """ Developer class provides common datas about developer """
    def __init__(self, username, load_from=''):
        self.username = username
        self.realname = ''
        self.email    = ''
        self.homedir  = ''
        self.svndir   = ''
        self.svnrepos = ''
        self.repos    = ''

        # internals
        self._repos = []

        if not load_from == '':
            # try to get developer information from given config file
            self.getDeveloperData(load_from)

    def set(self, attr, val):
        setattr(self, attr, val)

    def saveDeveloperData(self, path_to_config):
        """ Stores developer information to given config file """
        file(path_to_config,"w").close()
        config = ConfigParser.ConfigParser()
        config.add_section(DEVELOPER)
        for props in self.config.options(DEVELOPER):
            config.set(DEVELOPER,props,getattr(self, props))
        for repo in self._repos:
            reponame = "repo:%s" % repo.reponame
            config.add_section(reponame)
            config.set(reponame,"reponame",repo.reponame)
            config.set(reponame,"repoaddr",repo.repoaddr)
            config.set(reponame,"packages",','.join(map(lambda x: x.packagename, repo.packages)))
            for package in repo.packages:
                packagename = "package:%s" % package.packagename
                config.add_section(packagename)
                for var in dir(package):
                    if not var.startswith("_"):
                        config.set(packagename, var, getattr(package, var))
        config.write(file(path_to_config,"w"))
        print "Developer data saved."
        self.getDeveloperData(path_to_config)

    def getDeveloperData(self, path_to_config):
        """ Gets developer information from given config file """
        self.config = ConfigParser.ConfigParser()
        try:
            self.config.read(path_to_config)
            for props in self.config.options(DEVELOPER):
                setattr(self, props, self.config.get(DEVELOPER, props))
        except:
            raise Exceptions.FileCorrupted, "Config file %s is corrupted. " % path_to_config

        self.getRepos()
        self.getPackages()

    def getProps(self, tag):
        return self.config.get(DEVELOPER, tag)

    def getPackage(self, package):
        for section in self.config.sections():
            if section.startswith("package:") and section.endswith(package):
                pack = Package(package)
                for props in self.config.options(section):
                    setattr(pack, props, self.config.get(section, props))
                return pack
        raise Exceptions.NotFound, "There is no package info for %s, skipped." % package

    def getPackages(self):
        packages = []
        for repo in self._repos:
            for package in repo.packages:
                try:
                    packages.append(self.getPackage(package.packagename))
                except Exceptions.NotFound, e:
                    print e
        return packages

    def getRepos(self):
        for repo in self.repos.split(','):
            try:
                self.addRepo(self.getRepo(repo))
            except Exceptions.AlreadyExists:
                pass
            except Exceptions.NotFound, e:
                #print e
                pass
        return self._repos

    def getRepo(self, reponame):
        for section in self.config.sections():
            if section.startswith("repo:") and section.endswith(reponame):
                repo = Repo(reponame)
                repo.repoaddr = self.config.get(section,"repoaddr")
                repo.packages = map(lambda x: self.getPackage(x), self.config.get(section,"packages").split(','))
                return repo
        raise Exceptions.NotFound, "There is no repo named with %s " % reponame

    def addRepo(self, repo, force=False):
        for node in self._repos:
            if repo.reponame == node.reponame:
                if force:
                    self._repos.remove(node)
                else:
                    raise Exceptions.AlreadyExists, "Repo %s is already in list, skipped." % repo.reponame
        self._repos.append(repo)
        self.repos = ','.join(map(lambda x: x.reponame, self._repos))

